<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0"
    />
    <title>Map Editor</title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
    <link
      href="https://cdn.jsdelivr.net/npm/daisyui@4.11.1/dist/full.min.css"
      rel="stylesheet"
      type="text/css"
    />
    <script src="https://cdn.tailwindcss.com"></script>
    <style>
      table {
        border-collapse: collapse;
        margin: 0 auto;
      }
      td,
      .td {
        width: 32px;
        height: 32px;
        text-align: center;
        border: 1px solid #ccc;
      }
      .kbd,
      td {
        user-select: none;
      }
      .cell-0 {
        background-image: url('');
      }
      .cell-1 {
        background-image: url('');
      }
      .cell-2 {
        background-image: url('');
      }
      .cell-3 {
        background-image: url('');
      }
      .cell-4 {
        background-image: url('');
      }
      .cell-5 {
        background-image: url('');
      }
      .cell-6 {
        background-image: url('');
      }
    </style>
  </head>
  <body>
    <div
      id="app"
      class="p-4"
    >
      <div class="overflow-x-auto">
        <table>
          <tbody>
            <tr
              v-for="(row, rowIndex) in grid"
              :key="rowIndex"
            >
              <td
                v-for="(cell, cellIndex) in row"
                :key="cellIndex"
                @click="editCell(rowIndex, cellIndex)"
                :class="'cell-' + cell"
                class="border border-gray-300"
                unselectable="on"
              ></td>
            </tr>
          </tbody>
        </table>
      </div>
      <div class="mt-4">
        <div class="flex justify-center w-full">
          <kbd
            class="kbd"
            @click="moveContent('up')"
            >▲</kbd
          >
        </div>
        <div class="flex justify-center gap-12 w-full">
          <kbd
            class="kbd"
            @click="moveContent('left')"
            >◀︎</kbd
          >
          <kbd
            class="kbd"
            @click="moveContent('right')"
            >▶︎</kbd
          >
        </div>
        <div class="flex justify-center w-full">
          <kbd
            class="kbd"
            @click="moveContent('down')"
            >▼</kbd
          >
        </div>
        <div class="flex space-x-2 mt-4">
          <button
            @click="addRow"
            class="btn btn-accent"
          >
            添加行
          </button>
          <button
            @click="removeRow"
            class="btn btn-secondary"
          >
            删除行
          </button>
          <button
            @click="addColumn"
            class="btn btn-accent"
          >
            添加列
          </button>
          <button
            @click="removeColumn"
            class="btn btn-secondary"
          >
            删除列
          </button>
        </div>
        <div class="mt-4">
          <textarea
            v-model="exportData"
            class="textarea textarea-bordered w-full"
            rows="10"
          ></textarea>
        </div>
        <div class="flex space-x-2 mt-4">
          <button
            @click="importData"
            class="btn btn-accent"
          >
            加载数据
          </button>
          <button
            @click="exportDataFunc"
            class="btn btn-accent"
          >
            导出数据
          </button>
        </div>
      </div>

      <div class="divider">方块说明</div>

      <div class="flex flex-col w-full lg:flex-row">
        <div
          class="cell-0 td"
          unselectable="on"
        ></div>
        0：地板
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-1 td"
          unselectable="on"
        ></div>
        1：墙体
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-2 td"
          unselectable="on"
        ></div>
        2：终点
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-3 td"
          unselectable="on"
        ></div>
        3：箱子
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-4 td"
          unselectable="on"
        ></div>
        4：玩家
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-5 td"
          unselectable="on"
        ></div>
        5：进入终点的箱子
        <div class="divider lg:divider-horizontal"></div>
        <div
          class="cell-6 td"
          unselectable="on"
        ></div>
        6：在终点的玩家
      </div>
    </div>

    <script>
      new Vue({
        el: '#app',
        data: {
          grid: [
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
            [0, 0, 0, 1, 1, 1, 0, 0, 0, 0],
            [0, 0, 0, 1, 2, 1, 0, 0, 0, 0],
            [0, 0, 0, 1, 0, 1, 1, 1, 1, 0],
            [0, 1, 1, 1, 3, 0, 3, 2, 1, 0],
            [0, 1, 2, 0, 3, 4, 1, 1, 1, 0],
            [0, 1, 1, 1, 1, 3, 1, 0, 0, 0],
            [0, 0, 0, 0, 1, 2, 1, 0, 0, 0],
            [0, 0, 0, 0, 1, 1, 1, 0, 0, 0],
            [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
          ],
          exportData: '',
        },
        methods: {
          editCell(row, col) {
            this.grid[row][col] = (this.grid[row][col] + 1) % 7
            this.exportDataFunc()
          },
          moveContent(direction) {
            switch (direction) {
              case 'up':
                this.move(-1, 0)
                break
              case 'down':
                this.move(1, 0)
                break
              case 'left':
                this.move(0, -1)
                break
              case 'right':
                this.move(0, 1)
                break
            }
          },
          move(offsetY, offsetX) {
            const rows = this.grid.length
            const cols = this.grid[0].length
            let newGrid = []
            let canMove = true
            // Check the boundary based on the direction of movement
            if (offsetY === -1) {
              // Moving up: Check the top row
              for (let col = 0; col < cols; col++) {
                if (this.grid[0][col] !== 0) {
                  canMove = false
                  break
                }
              }
            } else if (offsetY === 1) {
              // Moving down: Check the bottom row
              for (let col = 0; col < cols; col++) {
                if (this.grid[rows - 1][col] !== 0) {
                  canMove = false
                  break
                }
              }
            } else if (offsetX === -1) {
              // Moving left: Check the leftmost column
              for (let row = 0; row < rows; row++) {
                if (this.grid[row][0] !== 0) {
                  canMove = false
                  break
                }
              }
            } else if (offsetX === 1) {
              // Moving right: Check the rightmost column
              for (let row = 0; row < rows; row++) {
                if (this.grid[row][cols - 1] !== 0) {
                  canMove = false
                  break
                }
              }
            }

            if (canMove) {
              for (let i = 0; i < rows; i++) {
                newGrid.push(Array(cols).fill(0))
                for (let k = 0; k < cols; k++) {
                  if (this.grid && this.grid[i - offsetY] && this.grid[i - offsetY][k - offsetX]) {
                    newGrid[i][k] = this.grid[i - offsetY][k - offsetX]
                  }
                }
              }
              this.grid = newGrid
            }
            this.exportDataFunc()
          },
          addRow() {
            const cols = this.grid[0].length
            this.grid.push(Array(cols).fill(0))
            this.exportDataFunc()
          },
          removeRow() {
            if (this.grid.length > 1) {
              this.grid.pop()
            }
            this.exportDataFunc()
          },
          addColumn() {
            this.grid.forEach((row) => row.push(0))
            this.exportDataFunc()
          },
          removeColumn() {
            if (this.grid[0].length > 1) {
              this.grid.forEach((row) => row.pop())
            }
            this.exportDataFunc()
          },
          importData() {
            try {
              this.grid = JSON.parse(this.exportData)
            } catch (e) {
              alert('Invalid data format')
            }
            this.exportDataFunc()
          },
          exportDataFunc() {
            this.exportData = JSON.stringify(this.grid)
          },
        },
      })
    </script>
  </body>
</html>
